#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "configdialog.h"
#include "ffmpegwrapper.h"
#include "capturewrapper.h"
#include "hsvwidget.h"
#include "hsvcolor.h"

#include <QtGui>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_configDialog = new ConfigDialog();
    m_ffmpegWrapper = new FFMPEGWrapper();
    m_captureWrapper = new CaptureWrapper(this);
    m_hsvWidget = new HSVWidget(this);
    m_zoomCombo = new QComboBox(this);
    m_zoomCombo->addItem("1");
    m_zoomCombo->addItem("2");
    m_zoomCombo->addItem("3");
    m_zoomCombo->addItem("4");
    m_zoomCombo->addItem("5");
    m_zoomCombo->addItem("6");

    connect(ui->m_actionConfig, SIGNAL(triggered()), this, SLOT(showConfig()));
    connect(ui->m_actionView, SIGNAL(triggered()), this, SLOT(createMovie()));
    connect(ui->m_actionSnapshot, SIGNAL(triggered()), this, SLOT(takeSnapshot()));
    connect(ui->m_frameWidget, SIGNAL(clicked(QString)), this, SLOT(showFrame(QString)));
    connect(ui->m_actionOnionSkinning, SIGNAL(toggled(bool)), this, SLOT(onionToggled()));
    connect(ui->m_actionDelete, SIGNAL(triggered()), this, SLOT(deleteFrame()));
    connect(ui->m_actionSetBackground, SIGNAL(triggered()), this, SLOT(setBackground()));
    connect(ui->m_onionWidget, SIGNAL(maskColorChoosen(HSVColor)), this, SLOT(maskChanged(HSVColor)));
    connect(m_hsvWidget, SIGNAL(colorChanged(HSVColor)), this, SLOT(maskChanged(HSVColor)));
    connect(ui->m_actionChromaKey, SIGNAL(toggled(bool)), ui->m_onionWidget, SLOT(setChromaKey(bool)));
    connect(ui->m_actionShowBackground, SIGNAL(toggled(bool)), ui->m_onionWidget, SLOT(setShowBackground(bool)));
    connect(m_zoomCombo, SIGNAL(currentIndexChanged(QString)), m_captureWrapper, SLOT(setZoom(QString)));
    connect(ui->m_actionFlash, SIGNAL(toggled(bool)), m_captureWrapper, SLOT(setFlash(bool)));

    ui->mainToolBar->addWidget(new QLabel(" Zoom: "));
    ui->mainToolBar->addWidget(m_zoomCombo);
    ui->mainToolBar->addWidget(m_hsvWidget);

    m_frameCount = 0;

    showConfig();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showConfig()
{
    if (m_configDialog->exec() == QDialog::Accepted)
    {
        m_configDialog->writeSettings();
    }
    else
    {
        m_configDialog->readSettings();
    }

    QSettings settings;
    m_prefix = settings.value("film/title").value<QString>();
    m_prefix = m_prefix.toLower().replace(" ", "_");

    m_workingDir = settings.value("film/directory").value<QString>();

    m_movieName = m_prefix + ".mp4";

    QDir thumbsDir(m_workingDir + "/thumbs");

    if (!thumbsDir.exists())
    {
        thumbsDir.mkdir(m_workingDir + "/thumbs");
    }

    loadThumbs();

    if (listFrames().size())
        showFrame(m_workingDir + "/" + listFrames().at(0));

    ui->m_onionWidget->setBackground(settings.value("film/background").value<QString>());
}

void MainWindow::loadThumbs()
{
    ui->m_frameWidget->clear();

    QList<QString> frameList = listFrames();

    for (int i = 0; i < frameList.size(); ++i)
    {
        ui->m_frameWidget->addFrame(m_workingDir + "/thumbs/" + frameList.at(i));
    }

    m_frameCount = frameList.size();

    ui->statusBar->showMessage(QString("Frames: %1").arg(m_frameCount));
}

QList<QString> MainWindow::listFrames()
{
    QList<QString> frameList;

    QStringList nameFilter(QLatin1String("*.jpg"));
    QDirIterator it(m_workingDir, nameFilter);

    while (it.hasNext()) {
        frameList << it.next().section('/', -1);
    }

    qSort(frameList);

    return frameList;
}

void MainWindow::showFrame(QString filename)
{
    m_lastFrame = filename;

    QList<QString> showList;

    if (ui->m_actionOnionSkinning->isChecked())
    {

        QList<QString> frameList = listFrames();


        int pos = frameList.indexOf(filename.section('/', -1));

        for (int i = pos; (i >= 0 && i > pos - 3); i--)
        {
            showList <<  m_workingDir + "/" + frameList.at(i);
        }
    }
    else
    {
        showList << filename.replace("/thumbs", "");
    }

    ui->m_onionWidget->showFrames(showList);
}

void MainWindow::onionToggled()
{
    showFrame(m_lastFrame);
}

void MainWindow::setBackground()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "", tr("JPEG Files (*.jpg)"));

    if (!fileName.isEmpty())
    {
        QSettings settings;

        settings.setValue("film/background", fileName);

        ui->m_onionWidget->setBackground(fileName);
    }
}

void MainWindow::maskChanged(HSVColor color)
{
    ui->m_onionWidget->setMaskColor(color);
    m_hsvWidget->setColor(color, true);
}

void MainWindow::takeSnapshot()
{
    m_frameCount++;

    QString fc = QString("%1").arg(m_frameCount);
    QString frameCountString = QString("%1").arg(fc, 6, '0');
    QString frameName = m_workingDir + "/" + m_prefix + frameCountString + ".jpg";
    QString smallFrameName = m_workingDir + "/thumbs/" + m_prefix + frameCountString + ".jpg";

    qDebug() << "taking" << frameName;

    m_captureWrapper->takeSnapshot(frameName);

    QFile bigfile(frameName);

    while(!bigfile.exists())
    {
       sleep(10);
    }

    QImage big(frameName);
    QImage small = big.scaledToWidth(100);
    small.save(smallFrameName);

    ui->m_frameWidget->addFrame(smallFrameName);

    ui->statusBar->showMessage(QString("Frames: %1").arg(m_frameCount));
}

void MainWindow::deleteFrame()
{
    if (!m_lastFrame.isEmpty())
    {
        if (QMessageBox::question(this, "Delete Frame", "Do you realy want to delete this Frame?", QMessageBox::Yes, QMessageBox::Cancel) == QMessageBox::Yes)
        {
            QFile thumb(m_lastFrame);
            thumb.remove();

            QFile frame(m_lastFrame.replace("/thumbs", ""));
            frame.remove();

            loadThumbs();
        }
    }
}

void MainWindow::createMovie()
{
    m_ffmpegWrapper->setPrefix(m_prefix);
    m_ffmpegWrapper->setWorkingDirectory(m_workingDir);
    m_ffmpegWrapper->setMovieName(m_movieName);
    m_ffmpegWrapper->run();
}
